using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using UniversalAdminSystem.Domian.PermissionManagement.Aggregate;
using UniversalAdminSystem.Domian.PermissionManagement.IRepository;
using UniversalAdminSystem.Domian.PermissionManagement.ValueObjects;
using UniversalAdminSystem.Domian.PermissionManagement.Services;
using UniversalAdminSystem.Domian.UserManagement.Aggregates;
using UniversalAdminSystem.Domian.UserManagement.IRepository;
using UniversalAdminSystem.Domian.UserManagement.ValueObj;
using UniversalAdminSystem.Application.Common.Interfaces;
using UniversalAdminSystem.Domian.UserManagement.Entities;
using UniversalAdminSystem.Application.UserManagement.Interface;

namespace UniversalAdminSystem.Infrastructure.Services;

public class SystemInitializationService : IHostedService
{
    private readonly SystemPermissionConfigLoader _loader;
    private readonly IServiceScopeFactory _scopeFactory;
    private static bool _initialized = false;

    public SystemInitializationService(
        SystemPermissionConfigLoader loader,
        IServiceScopeFactory scopeFactory
    )
    {
        _loader = loader;
        _scopeFactory = scopeFactory;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        if (_initialized)
        {
            return;
        }

        cancellationToken.ThrowIfCancellationRequested();

        try
        {
            // 首先加载权限规则配置
            var rulesConfigPath = Path.Combine(AppContext.BaseDirectory, "PermissionRules.json");
            if (File.Exists(rulesConfigPath))
            {
                var rulesContent = await File.ReadAllTextAsync(rulesConfigPath, cancellationToken);
                var rulesDict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, List<string>>>(rulesContent);
                
                if (rulesDict != null)
                {
                    var rules = rulesDict.ToDictionary(
                        kv => Enum.Parse<PermissionAction>(kv.Key, true),
                        kv => kv.Value.ToHashSet()
                    );
                    
                    ResourceActionValidator.LoadRules(rules);
                    Console.WriteLine("权限规则配置加载成功");
                }
            }
            else
            {
                Console.WriteLine("权限规则配置文件不存在，使用默认配置");
                // 设置默认规则
                var defaultRules = new Dictionary<PermissionAction, HashSet<string>>
                {
                    { PermissionAction.Read, new HashSet<string> { "data", "file", "user", "role", "permission", "config", "system" } },
                    { PermissionAction.Create, new HashSet<string> { "data", "user", "file", "role", "permission" } },
                    { PermissionAction.Update, new HashSet<string> { "data", "user", "config", "role", "permission" } },
                    { PermissionAction.Delete, new HashSet<string> { "data", "user", "file", "role", "permission" } },
                    { PermissionAction.Manage, new HashSet<string> { "system", "user" } }
                };
                ResourceActionValidator.LoadRules(defaultRules);
            }

            // 初始化到数据库
            using (var scope = _scopeFactory.CreateScope())
            {
                var permissionRepository = scope.ServiceProvider.GetRequiredService<IPermissionRepository>();
                var roleRepository = scope.ServiceProvider.GetRequiredService<IRoleRepository>();
                var userRepository = scope.ServiceProvider.GetRequiredService<IUserRepository>();
                var userInfoRepository = scope.ServiceProvider.GetRequiredService<IUserInfoRepository>();
                var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
                var passwordHelper = scope.ServiceProvider.GetRequiredService<IPasswordHelper>();

                // 1. 创建系统权限
                Console.WriteLine("开始创建系统权限...");
                var systemPermissions = CreateSystemPermissions();
                await permissionRepository.AddSystemPermissionsAsync(systemPermissions);
                Console.WriteLine($"成功创建 {systemPermissions.Count} 个系统权限");

                // 2. 创建角色
                Console.WriteLine("开始创建角色...");
                var roles = await CreateRolesAsync(roleRepository, permissionRepository);
                Console.WriteLine($"成功创建 {roles.Count} 个角色");

                // 3. 提交角色创建到数据库
                Console.WriteLine("提交角色创建到数据库...");
                await unitOfWork.SaveChangesAsync();
                Console.WriteLine("角色创建提交成功");

                // 4. 为超级管理员分配所有权限（使用安全方法）
                Console.WriteLine("开始为超级管理员分配权限...");
                var superAdminRole = await roleRepository.GetByNameAsync("超级管理员");
                if (superAdminRole != null)
                {
                    await AssignAllPermissionsToRoleSafely(superAdminRole, permissionRepository);
                    Console.WriteLine("超级管理员权限分配完成");
                }

                // 5. 为管理员分配管理权限
                Console.WriteLine("开始为管理员分配权限...");
                var adminRole = await roleRepository.GetByNameAsync("管理员");
                if (adminRole != null)
                {
                    await AssignAdminPermissionsToRoleSafely(adminRole, permissionRepository);
                    Console.WriteLine("管理员权限分配完成");
                }

                // 6. 为普通用户分配基本权限
                Console.WriteLine("开始为普通用户分配权限...");
                var normalUserRole = await roleRepository.GetByNameAsync("普通用户");
                if (normalUserRole != null)
                {
                    await AssignBasicPermissionsToRoleSafely(normalUserRole, permissionRepository);
                    Console.WriteLine("普通用户权限分配完成");
                }

                // 7. 创建超级管理员用户
                await CreateSuperAdminAsync(userRepository, userInfoRepository, roleRepository, passwordHelper);
                Console.WriteLine("成功创建超级管理员用户");

                // 8. 创建管理员用户
                await CreateAdminUserAsync(userRepository, userInfoRepository, roleRepository, passwordHelper);
                Console.WriteLine("成功创建管理员用户");

                // 9. 提交所有更改到数据库
                Console.WriteLine("开始提交数据库更改...");
                await unitOfWork.BeginTransactionAsync();
                await unitOfWork.CommitAsync();
                Console.WriteLine("数据库更改提交成功");

                _initialized = true;
                Console.WriteLine("系统初始化完成");
            }
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("初始化系统失败", ex);
        }
    }

    private List<Permission> CreateSystemPermissions()
    {
        var permissions = new List<Permission>();

        // 文件权限
        permissions.Add(Permission.CreateSystemPermission("文件上传", "file", (int)PermissionAction.Create));
        permissions.Add(Permission.CreateSystemPermission("文件下载", "file", (int)PermissionAction.Read));
        permissions.Add(Permission.CreateSystemPermission("文件删除", "file", (int)PermissionAction.Delete));
        permissions.Add(Permission.CreateSystemPermission("文档权限", "document", (int)PermissionAction.Private));
        permissions.Add(Permission.CreateSystemPermission("文档权限", "document", (int)PermissionAction.Public));
        permissions.Add(Permission.CreateSystemPermission("文档权限", "document", (int)PermissionAction.Restricted));
        permissions.Add(Permission.CreateSystemPermission("文档权限", "document", (int)PermissionAction.Read));

        // 用户权限
        permissions.Add(Permission.CreateSystemPermission("创建用户", "user", (int)PermissionAction.Create));
        permissions.Add(Permission.CreateSystemPermission("查看用户", "user", (int)PermissionAction.Read));
        permissions.Add(Permission.CreateSystemPermission("更新用户", "user", (int)PermissionAction.Update));
        permissions.Add(Permission.CreateSystemPermission("删除用户", "user", (int)PermissionAction.Delete));

        // 角色权限
        permissions.Add(Permission.CreateSystemPermission("创建角色", "role", (int)PermissionAction.Create));
        permissions.Add(Permission.CreateSystemPermission("查看角色", "role", (int)PermissionAction.Read));
        permissions.Add(Permission.CreateSystemPermission("更新角色", "role", (int)PermissionAction.Update));
        permissions.Add(Permission.CreateSystemPermission("删除角色", "role", (int)PermissionAction.Delete));

        // 权限管理
        permissions.Add(Permission.CreateSystemPermission("创建权限", "permission", (int)PermissionAction.Create));
        permissions.Add(Permission.CreateSystemPermission("查看权限", "permission", (int)PermissionAction.Read));
        permissions.Add(Permission.CreateSystemPermission("更新权限", "permission", (int)PermissionAction.Update));
        permissions.Add(Permission.CreateSystemPermission("删除权限", "permission", (int)PermissionAction.Delete));

        // 系统管理
        permissions.Add(Permission.CreateSystemPermission("系统管理", "system", (int)PermissionAction.Manage));

        return permissions;
    }

    private async Task<List<Role>> CreateRolesAsync(IRoleRepository roleRepository, IPermissionRepository permissionRepository)
    {
        var roles = new List<Role>();

        // 检查是否已存在超级管理员角色
        var existingSuperAdmin = await roleRepository.GetByNameAsync("超级管理员");
        if (existingSuperAdmin == null)
        {
            // 1. 超级管理员角色
            var superAdminRole = Role.Create("超级管理员", "系统最高权限管理员", true, true);
            Console.WriteLine($"创建超级管理员角色: {superAdminRole.Name.Value} (ID: {superAdminRole.RoleId.Value})");
            await roleRepository.AddAsync(superAdminRole);
            roles.Add(superAdminRole);
        }
        else
        {
            Console.WriteLine($"超级管理员角色已存在: {existingSuperAdmin.Name.Value}");
            roles.Add(existingSuperAdmin);
        }

        // 检查是否已存在管理员角色
        var existingAdmin = await roleRepository.GetByNameAsync("管理员");
        if (existingAdmin == null)
        {
            // 2. 管理员角色
            var adminRole = Role.Create("管理员", "系统管理员", true, false);
            Console.WriteLine($"创建管理员角色: {adminRole.Name.Value} (ID: {adminRole.RoleId.Value})");
            await roleRepository.AddAsync(adminRole);
            roles.Add(adminRole);
        }
        else
        {
            Console.WriteLine($"管理员角色已存在: {existingAdmin.Name.Value}");
            roles.Add(existingAdmin);
        }

        // 检查是否已存在普通用户角色
        var existingNormalUser = await roleRepository.GetByNameAsync("普通用户");
        if (existingNormalUser == null)
        {
            // 3. 普通用户角色
            var normalUserRole = Role.Create("普通用户", "普通用户", true, false);
            Console.WriteLine($"创建普通用户角色: {normalUserRole.Name.Value} (ID: {normalUserRole.RoleId.Value})");
            await roleRepository.AddAsync(normalUserRole);
            roles.Add(normalUserRole);
        }
        else
        {
            Console.WriteLine($"普通用户角色已存在: {existingNormalUser.Name.Value}");
            roles.Add(existingNormalUser);
        }

        Console.WriteLine("角色创建完成，暂时跳过权限分配");

        return roles;
    }

    private async Task AssignAllPermissionsToRoleSafely(Role role, IPermissionRepository permissionRepository)
    {
        Console.WriteLine($"开始为角色 {role.Name.Value} 分配所有权限...");
        
        // 获取所有权限ID（避免实体跟踪冲突）
        var allPermissions = await permissionRepository.GetAllAsync();
        var permissionIds = allPermissions.Select(p => p.PermissionId).ToList();
        
        Console.WriteLine($"找到 {permissionIds.Count} 个权限");
        
        // 为角色分配所有权限（使用ID而不是实体）
        foreach (var permissionId in permissionIds)
        {
            if (!role.HasPermission(permissionId))
            {
                // 通过ID查找权限实体，避免重复跟踪
                var permission = await permissionRepository.GetByGuidAsync(permissionId);
                if (permission != null)
                {
                    role.AddPermission(permission);
                }
            }
        }
        
        Console.WriteLine($"成功为角色 {role.Name.Value} 分配了 {permissionIds.Count} 个权限");
    }

    private async Task AssignAdminPermissionsToRoleSafely(Role role, IPermissionRepository permissionRepository)
    {
        // 获取管理员需要的权限
        var adminPermissionCodes = new[]
        {
            "user:Create", "user:Read", "user:Update", "user:Delete",
            "role:Create", "role:Read", "role:Update", "role:Delete",
            "permission:Create", "permission:Read", "permission:Update", "permission:Delete",
            "system:Manage",
            "file:Read","file:Create","file:Delete",
            "document:Restricted","document:Read"
        };

        var adminPermissionIds = new List<Guid>();
        foreach (var code in adminPermissionCodes)
        {
            var permission = await permissionRepository.GetByCodeAsync(PermissionCode.Create(code));
            if (permission != null)
            {
                adminPermissionIds.Add(permission.PermissionId);
            }
        }

        // 为角色分配权限（使用ID而不是实体）
        foreach (var permissionId in adminPermissionIds)
        {
            if (!role.HasPermission(permissionId))
            {
                // 通过ID查找权限实体，避免重复跟踪
                var permission = await permissionRepository.GetByGuidAsync(permissionId);
                if (permission != null)
                {
                    role.AddPermission(permission);
                }
            }
        }
        Console.WriteLine($"为角色 {role.Name.Value} 分配了 {adminPermissionIds.Count} 个管理权限");
    }

    private async Task AssignBasicPermissionsToRoleSafely(Role role, IPermissionRepository permissionRepository)
    {
        // 获取普通用户需要的基本权限
        var basicPermissionCodes = new[]
        {
            "user:Read", "role:Read", "permission:Read",
            "file:Create", "file:Read",
            "document:Read","document:Restricted"
        };

        var basicPermissionIds = new List<Guid>();
        foreach (var code in basicPermissionCodes)
        {
            var permission = await permissionRepository.GetByCodeAsync(PermissionCode.Create(code));
            if (permission != null)
            {
                basicPermissionIds.Add(permission.PermissionId);
            }
        }

        // 为角色分配权限（使用ID而不是实体）
        foreach (var permissionId in basicPermissionIds)
        {
            if (!role.HasPermission(permissionId))
            {
                // 通过ID查找权限实体，避免重复跟踪
                var permission = await permissionRepository.GetByGuidAsync(permissionId);
                if (permission != null)
                {
                    role.AddPermission(permission);
                }
            }
        }
        Console.WriteLine($"为角色 {role.Name.Value} 分配了 {basicPermissionIds.Count} 个基本权限");
    }

    private async Task CreateSuperAdminAsync(
        IUserRepository userRepository, 
        IUserInfoRepository userInfoRepository,
        IRoleRepository roleRepository,
        IPasswordHelper passwordHelper)
    {
        // 检查是否已存在超级管理员
        var existingSuperAdmin = await userRepository.GetUserByAccountAsync(UserAccount.Create("admin123"));
        if (existingSuperAdmin != null)
        {
            Console.WriteLine("超级管理员已存在，跳过创建");
            return;
        }

        Console.WriteLine("开始创建超级管理员...");

        // 创建用户信息
        var userInfo = UserInfo.CreateUserInfo(
            "超级管理员",
            UserGender.Man,
            null,
            "系统超级管理员"
        );
        await userInfoRepository.AddAsync(userInfo);
        Console.WriteLine("用户信息创建成功");

        // 获取超级管理员角色
        Console.WriteLine("开始查找超级管理员角色...");
        var superAdminRole = await roleRepository.GetByNameAsync("超级管理员");
        if (superAdminRole == null)
        {
            // 尝试获取所有角色来调试
            var allRoles = await roleRepository.GetAllAsync();
            Console.WriteLine($"数据库中所有角色数量: {allRoles.Count()}");
            foreach (var role in allRoles)
            {
                Console.WriteLine($"角色: {role.Name.Value} (ID: {role.RoleId.Value})");
            }
            
            // 尝试直接通过ID查找
            Console.WriteLine("尝试通过ID查找角色...");
            var rolesById = await roleRepository.GetAllRolesWithPermissionsAsync();
            foreach (var role in rolesById)
            {
                Console.WriteLine($"通过ID找到角色: {role.Name.Value} (ID: {role.RoleId.Value})");
            }
            
            throw new InvalidOperationException("超级管理员角色不存在");
        }
        Console.WriteLine($"获取超级管理员角色成功: {superAdminRole.Name.Value} (ID: {superAdminRole.RoleId.Value})");

        // 加密密码
        var (hashedPassword, salt) = passwordHelper.HashPasswordWithSeparateSalt("admin123");
        
        // 创建超级管理员用户
        var superAdmin = User.CreateUser(
            userInfo.UserInfoId,
            "admin123", // 修改为符合格式要求的账号
            hashedPassword, // 加密后的密码
            "admin@system.com",
            salt, // 加密盐值
            UserStatus.Normal,
            superAdminRole.RoleId.Value
        );

        await userRepository.AddAsync(superAdmin);
        Console.WriteLine("超级管理员用户创建成功");

        Console.WriteLine("超级管理员创建成功");
        Console.WriteLine("账号: admin123");
        Console.WriteLine("密码: admin123");
    }

    private async Task CreateAdminUserAsync(
        IUserRepository userRepository, 
        IUserInfoRepository userInfoRepository,
        IRoleRepository roleRepository,
        IPasswordHelper passwordHelper)
    {
        // 检查是否已存在管理员用户
        var existingAdmin = await userRepository.GetUserByAccountAsync(UserAccount.Create("manager"));
        if (existingAdmin != null)
        {
            Console.WriteLine("管理员用户已存在，跳过创建");
            return;
        }

        Console.WriteLine("开始创建管理员用户...");

        // 创建用户信息
        var userInfo = UserInfo.CreateUserInfo(
            "系统管理员",
            UserGender.Man,
            null,
            "系统管理员，负责日常系统管理"
        );
        await userInfoRepository.AddAsync(userInfo);
        Console.WriteLine("管理员用户信息创建成功");

        // 获取管理员角色
        Console.WriteLine("开始查找管理员角色...");
        var adminRole = await roleRepository.GetByNameAsync("管理员");
        if (adminRole == null)
        {
            // 尝试获取所有角色来调试
            var allRoles = await roleRepository.GetAllAsync();
            Console.WriteLine($"数据库中所有角色数量: {allRoles.Count()}");
            foreach (var role in allRoles)
            {
                Console.WriteLine($"角色: {role.Name.Value} (ID: {role.RoleId.Value})");
            }
            
            throw new InvalidOperationException("管理员角色不存在");
        }
        Console.WriteLine($"获取管理员角色成功: {adminRole.Name.Value} (ID: {adminRole.RoleId.Value})");

        // 加密密码
        var (hashedPassword, salt) = passwordHelper.HashPasswordWithSeparateSalt("manager123");
        
        // 创建管理员用户
        var admin = User.CreateUser(
            userInfo.UserInfoId,
            "manager", // 管理员账号
            hashedPassword, // 加密后的密码
            "manager@system.com",
            salt, // 加密盐值
            UserStatus.Normal,
            adminRole.RoleId.Value
        );

        await userRepository.AddAsync(admin);
        Console.WriteLine("管理员用户创建成功");

        Console.WriteLine("管理员用户创建成功");
        Console.WriteLine("账号: manager");
        Console.WriteLine("密码: manager123");
        Console.WriteLine("角色: 管理员");
    }

    /// <summary>
    /// 清理重复的权限数据
    /// </summary>
    private async Task CleanupDuplicatePermissionsAsync(IPermissionRepository permissionRepository)
    {
        try
        {
            Console.WriteLine("开始清理重复的权限数据...");
            
            // 获取所有权限
            var allPermissions = await permissionRepository.GetAllAsync();
            var permissionGroups = allPermissions.GroupBy(p => p.Code.Value).ToList();
            
            var duplicates = permissionGroups.Where(g => g.Count() > 1).ToList();
            
            if (duplicates.Any())
            {
                Console.WriteLine($"发现 {duplicates.Count} 个重复的权限代码");
                
                foreach (var group in duplicates)
                {
                    Console.WriteLine($"权限代码 '{group.Key}' 有 {group.Count()} 个重复项");
                    
                    // 保留第一个，删除其他的
                    var toKeep = group.First();
                    var toDelete = group.Skip(1).ToList();
                    
                    Console.WriteLine($"保留权限ID: {toKeep.PermissionId}, 删除 {toDelete.Count} 个重复项");
                    
                    // 这里需要实现删除方法，暂时跳过
                    // foreach (var perm in toDelete)
                    // {
                    //     await permissionRepository.DeleteAsync(perm.PermissionId);
                    // }
                }
            }
            else
            {
                Console.WriteLine("没有发现重复的权限数据");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"清理重复权限时出错: {ex.Message}");
        }
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
} 